import Obj3D from '../Poly2/Obj3D.js';
import Geo from '../Poly2/Geo.js';
import Mat from '../Poly2/Mat.js';

const defAttr = () => ({
    pointSize: 50,

    //默认配制
    margin: 0.5,//弧线开始的距离[0-0.5]
    arcGap: 0.05,//两条线的差距
    whiteDiff: 0.05,//白色外扩
    lineDia: 0.0,//白色直径
    blueDiff: 0.005,//蓝色外扩
    blueDia: 0.05 - 0.025,//蓝色直径

    // whiteDiff * 2 = blueDia + blueDiff * 2 = 完全覆盖
    // 总直径 = whiteDiff * 2 + lineDia
    // defConfig第二层参数 = 第一层参数 - 总直径 - 一般0.01重叠

    color1: [0.30, 0.53, 1, 0.5],
    color2: [1, 1, 1, 0.5],

    program: '',
    gl: null,
});

//弧线
export default class Arc {
    constructor(attr) {
        Object.assign(this, defAttr(), attr);
    }

    getElement(point) {
        return this._createBroder(point);
    }

    getInsideArcMargin() {
        const { margin, arcGap, whiteDiff, lineDia } = this;
        return margin - arcGap - (whiteDiff * 2 + lineDia) + 0.04;
    }

    _createBroder(point) {
        const { margin, arcGap, gl } = this;
        let Arc = new Obj3D({ depthTest: false });
        //短线
        const configs = this._createArcConfigOfDouble(point, margin);
        Arc.add(gl, this._createArcOfDouble(configs));
        //长线
        const configsL = this._createArcConfigOfDouble(point, margin - arcGap);
        configsL[0].Angle = [configs[0].Angle[1] - 10, configs[0].Angle[0] + 10];
        configsL[1].Angle = [configs[0].Angle[1] - 10, configs[0].Angle[0] + 10];
        Arc.add(gl, this._createArcOfDouble(configsL));

        return Arc;
    }

    //创建弧线配制
    _createArcConfigOfDouble(point, margin) {
        const { whiteDiff, lineDia, blueDiff, blueDia, color1, color2 } = this;

        let angleStart = Math.random() * 360;
        let angleEnd = angleStart + Math.random() * 90 + 45;
        angleEnd = angleEnd > 360 ? angleEnd - 360 : angleEnd;

        const config1 = {
            a_Position: point,
            lineStart: margin,
            lineDia: 0,
            lineDiff: whiteDiff,
            lineColor: color1,
            Angle: [angleStart, angleEnd],
        };

        const config2 = {
            a_Position: point,
            lineStart: margin - whiteDiff - lineDia / 2 + blueDiff + (blueDia / 2),
            lineDia: blueDia,
            lineDiff: blueDiff,
            lineColor: color2,
            Angle: [angleStart, angleEnd],
        };
        return [config1, config2];
    }

    _createArcOfDouble(configs) {
        const objW = this._createArc(configs[0]);
        const objB = this._createArc(configs[1]);
        objW.add(this.gl, objB);

        return objW;
    }

    _createArc(config) {
        const { a_Position, lineStart, lineDia, lineDiff, lineColor, Angle } = config;
        const { pointSize, program } = this;
        return new Obj3D({
            depthTest: false,
            geo: new Geo({
                data: {
                    'a_Position': { size: 2, array: new Float32Array([a_Position.x, a_Position.y]) },
                },
            }),
            mat: new Mat({
                program: program,
                mode: ['POINTS'],
                data: {
                    'u_PointSize': { type: 'uniform1f', value: pointSize },
                    'u_Angle': { type: 'uniform2fv', value: Angle },
                    'u_Set': { type: 'uniform1f', value: 0 },
                    'u_Line': { type: 'uniform3fv', value: [lineStart, lineDia, lineDiff] },
                    'u_line_Color': { type: 'uniform4fv', value: lineColor },
                },
            }),
        });
    }
}